package com.crawler.waf.exceptions.support;

import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;

import com.crawler.waf.exceptions.extendExceptions.WafSimpleException;
import com.crawler.waf.exceptions.extendExceptions.WafStandedException;
import com.crawler.waf.exceptions.extendExceptions.UcAuthenticationException;
import com.crawler.waf.exceptions.handlers.WafCustomExceptionHandler;
import com.crawler.waf.exceptions.handlers.WafDefaultExceptionHandler;
import com.crawler.waf.exceptions.handlers.WafExceptionHandler;

/**
 * 配置异常类所对应的异常捕获器和异常的响应码以及相应信息
 */
public enum WafErrorMessageMapper {
	// 默认错误
	DEFAULT_ERROR(Exception.class, new WafDefaultExceptionHandler(
			HttpStatus.INTERNAL_SERVER_ERROR)),
	// 404错误异常
	NO_SUCH_REQUEST_HANDLING_METHOD(NoSuchRequestHandlingMethodException.class,
			new WafDefaultExceptionHandler(HttpStatus.NOT_FOUND,
					"WAF/URI_NOT_FOUND")),
	// 请求方法不被支持
	HTTP_METHOD_NOT_SUPPORTED(HttpRequestMethodNotSupportedException.class,
			new WafDefaultExceptionHandler(HttpStatus.METHOD_NOT_ALLOWED,
					"WAF/METHOD_NOT_ALLOWED")),
	// 媒体类型不被支持
	HTTP_MEDIATYPE_NOT_SUPPORTED(HttpMediaTypeNotSupportedException.class,
			new WafDefaultExceptionHandler(HttpStatus.UNSUPPORTED_MEDIA_TYPE,
					"WAF/UNSUPPORTED_MEDIA_TYPE")),
	// 方法参数验证异常
	METHOD_ARGUMENT_NOT_VALID(MethodArgumentNotValidException.class,
			new WafDefaultExceptionHandler(HttpStatus.BAD_REQUEST,
					"WAF/INVALID_ARGUMENT")),
	// 绑定异常
	BIND_ERROR(BindException.class, new WafDefaultExceptionHandler(
			HttpStatus.BAD_REQUEST, "WAF/INVALID_ARGUMENT")),
	// 转换异常
	CONVERSION_NOT_SUPPORT(ConversionNotSupportedException.class,
			new WafDefaultExceptionHandler(HttpStatus.BAD_REQUEST,
					"WAF/BAD_REQUEST")),
	// 请求资源类型无法接受
	HTTP_MEDIATYPE_NOT_ACCEPTABLE(HttpMediaTypeNotAcceptableException.class,
			new WafDefaultExceptionHandler(HttpStatus.NOT_ACCEPTABLE,
					"WAF/NOT_ACCEPTABLE")),
	// 读取异常
	HTTP_MESSAGE_NOT_READABLE(HttpMessageNotReadableException.class,
			new WafDefaultExceptionHandler(HttpStatus.BAD_REQUEST,
					"WAF/INVALID_ARGUMENT")),
	// 写入异常
	HTTP_MESSAGE_NOT_WRITABLE(HttpMessageNotWritableException.class,
			new WafDefaultExceptionHandler(HttpStatus.BAD_REQUEST)),
	// 请求参数缺失
	MISSING_REQUEST_PARAMETER(MissingServletRequestParameterException.class,
			new WafDefaultExceptionHandler(HttpStatus.BAD_REQUEST,
					"WAF/REQUIRE_ARGUMENT")),
	// 请求部分缺失
	MISSING_REQUEST_PART(MissingServletRequestPartException.class,
			new WafDefaultExceptionHandler(HttpStatus.BAD_REQUEST,
					"WAF/REQUIRE_ARGUMENT")),
	// 404错误
	NOT_FOUND(NoHandlerFoundException.class, new WafDefaultExceptionHandler(
			HttpStatus.NOT_FOUND, "WAF/URI_NOT_FOUND")),
	// 请求绑定异常
	REQUEST_BIND_ERROR(ServletRequestBindingException.class,
			new WafDefaultExceptionHandler(HttpStatus.BAD_REQUEST,
					"WAF/BAD_REQUEST")),
	// 类型匹配异常
	TYPE_MISMATCH(TypeMismatchException.class, new WafDefaultExceptionHandler(
			HttpStatus.BAD_REQUEST, "WAF/BAD_REQUEST")),
	// 访问拒绝
	ACCESS_DENIED(AccessDeniedException.class, new WafDefaultExceptionHandler(
			HttpStatus.FORBIDDEN, "WAF/ACCESS_DENIED")),

	// 认证信息不全，或者头信息格式错误
	INSUFFICIENT_AUTHENTICATION(InsufficientAuthenticationException.class,
			new WafDefaultExceptionHandler(HttpStatus.UNAUTHORIZED,
					"WAF/AUTH_INVALID_TOKEN")),
	// 认证错误
	WAF_AUTHENTICATION_ERROR(UcAuthenticationException.class,
			new WafCustomExceptionHandler(HttpStatus.UNAUTHORIZED)),
	// 认证凭据没找到
	AUTHENTICATION_CREDENTIAL_NOT_FOUND(
			AuthenticationCredentialsNotFoundException.class,
			new WafDefaultExceptionHandler(HttpStatus.UNAUTHORIZED,
					"WAF/AUTH_ERROR")),
	// 自定义简单错误的处理
	WAF_SIMPLE_ERROR(WafSimpleException.class, new WafCustomExceptionHandler(
			HttpStatus.INTERNAL_SERVER_ERROR)),
	// 自定义标准异常的处理机制
	WAF_STANDED_ERROR(WafStandedException.class, new WafCustomExceptionHandler(
			HttpStatus.INTERNAL_SERVER_ERROR));

	private final Class<?> exClass;
	private final WafExceptionHandler handler;

	WafErrorMessageMapper(final Class<?> exClass,
			final WafExceptionHandler handler) {
		this.exClass = exClass;
		this.handler = handler;

	}

	public Class<?> getExClass() {
		return exClass;
	}

	public WafExceptionHandler getHandler() {
		return handler;
	}
}
